#![allow(unused_imports,dead_code,unused_assignments)]
use axum::{
    extract::{Form, Query, Json, Multipart,DefaultBodyLimit},
    routing::{get,post},
    response::Response,
    body::{Body, Bytes},
    Router
};
use crate::domain::RoleBean;
use crate::domain::RoleQueryRequest;
use crate::serviceimpl::role_service::activate_all_roles as service_activate_all_roles;
use crate::serviceimpl::role_service::activate_role as service_activate_role;
use crate::serviceimpl::role_service::add_role as service_add_role;
use crate::serviceimpl::role_service::assign_permissions_to_role as service_assign_permissions_to_role;
use crate::serviceimpl::role_service::clone_all_roles as service_clone_all_roles;
use crate::serviceimpl::role_service::clone_role as service_clone_role;
use crate::serviceimpl::role_service::count_search_roles_by_fields_records as service_count_search_roles_by_fields_records;
use crate::serviceimpl::role_service::delete_all_roles as service_delete_all_roles;
use crate::serviceimpl::role_service::delete_role as service_delete_role;
use crate::serviceimpl::role_service::find_role_by_id as service_find_role_by_id;
use crate::serviceimpl::role_service::find_role_by_role_name as service_find_role_by_role_name;
use crate::serviceimpl::role_service::list_active_role_permissions_using_role_id as service_list_active_role_permissions_using_role_id;
use crate::serviceimpl::role_service::list_active_roles as service_list_active_roles;
use crate::serviceimpl::role_service::list_all_roles as service_list_all_roles;
use crate::serviceimpl::role_service::list_available_active_role_permissions_using_role_id as service_list_available_active_role_permissions_using_role_id;
use crate::serviceimpl::role_service::revoke_permissions_from_role as service_revoke_permissions_from_role;
use crate::serviceimpl::role_service::search_roles_by_fields as service_search_roles_by_fields;
use crate::serviceimpl::role_service::search_roles_by_fields_by_page as service_search_roles_by_fields_by_page;
use crate::serviceimpl::role_service::soft_delete_all_roles as service_soft_delete_all_roles;
use crate::serviceimpl::role_service::soft_delete_role as service_soft_delete_role;
use crate::serviceimpl::role_service::toggle_one_role as service_toggle_one_role;
use crate::serviceimpl::role_service::toggle_role as service_toggle_role;
use crate::serviceimpl::role_service::update_role as service_update_role;
use crate::utils::excel_util::export_excel_workbook_with_image;
use crate::utils::pdf_util::export_pdf_with_images;
use serde::{Deserialize};
use serde_json::{Value,Map};
use std::fs;
use tower_http::{trace::TraceLayer};


#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RoleRequest {
	pub id: Option<i64>,
	pub role_name: Option<String>,
	pub active: Option<bool>,
}

#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct IdsRequest {
	pub ids: String,
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RolePermissionMtmRequest {
	pub role_id: Option<i64>,
	pub permission_ids:Option<String>,
}


pub fn role_controller() -> Router {
	Router::new()
	.route("/listAllRoles", post(list_all_roles))
	.route("/updateRole", post(update_role))
	.route("/deleteRole", post(delete_role))
	.route("/addRole", post(add_role))
	.route("/softDeleteRole", post(soft_delete_role))
	.route("/findRoleById", post(find_role_by_id))
	.route("/findRoleByRoleName", post(find_role_by_role_name))
	.route("/listActiveRoles", post(list_active_roles))
	.route("/deleteAllRoles", post(delete_all_roles))
	.route("/softDeleteAllRoles", post(soft_delete_all_roles))
	.route("/toggleRole", post(toggle_role))
	.route("/toggleOneRole", post(toggle_one_role))
	.route("/searchRolesByFieldsByPage", post(search_roles_by_fields_by_page))
	.route("/activateRole", post(activate_role))
	.route("/activateAllRoles", post(activate_all_roles))
	.route("/exportRoles", get(export_roles))
	.route("/exportRolesPDF", get(export_roles_pdf))
	.route("/filterRolesExcel", get(filter_roles_excel))
	.route("/filterRolesPDF", get(filter_roles_pdf))
	.route("/cloneRole", post(clone_role))
	.route("/cloneAllRoles", post(clone_all_roles))
	.route("/checkAccessRole", get(check_access_role))
	.route("/assignPermissionsToRole", post(assign_permissions_to_role))
	.route("/revokePermissionsFromRole", post(revoke_permissions_from_role))
	.route("/listActiveRolePermissionsUsingRoleId", post(list_active_role_permissions_using_role_id))
	.route("/listAvailableActiveRolePermissionsUsingRoleId", post(list_available_active_role_permissions_using_role_id))
	.layer(DefaultBodyLimit::max(2*1024*1024))
	.layer(TraceLayer::new_for_http())
}
pub async fn activate_all_roles(Form(ids_request):Form<IdsRequest>) ->String {
	let ids = ids_request.ids;
	let string_ids:Vec<&str> = ids.split(',').collect();
	let mut ids:Vec<i64> = Vec::new();

	let vecter_iterator = string_ids.iter();
	for id in vecter_iterator {
		ids.push(id.parse::<i64>().unwrap());
	}

	let _result = service_activate_all_roles(ids).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn activate_role(Form(role_request):Form<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let _result = service_activate_role(id).await;
	match _result {
		Err(_) => {
			println!("Error!");
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			//println!("{}", resultjson);
			return resultjson;
		}
	}
}

pub async fn add_role(Json(role_request):Json<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let role_name = role_request.role_name.unwrap_or_default();
	let active = role_request.active.unwrap_or_default();

	let role = RoleBean{
	id : id,
	role_name : role_name,
	active : active,
	};
	
	let _result = service_add_role(role).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn assign_permissions_to_role(Form(role_permission_mtm_request):Form<RolePermissionMtmRequest>) ->String {
	let role_id = role_permission_mtm_request.role_id.unwrap_or_default();
	let permission_ids_str = role_permission_mtm_request.permission_ids.unwrap_or_default();
	let string_ids:Vec<&str> = permission_ids_str.split(',').collect();
	let mut permission_ids:Vec<i64> = Vec::new();

	let vecter_iterator = string_ids.iter();
	for permission_id in vecter_iterator {
		permission_ids.push(permission_id.parse::<i64>().unwrap());
	}

	let _result = service_assign_permissions_to_role(role_id,permission_ids).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn check_access_role() ->String {
	r#"{  "rows": null,  "success": true}"#.to_string()
}

pub async fn clone_all_roles(Form(ids_request):Form<IdsRequest>) ->String {
	let ids = ids_request.ids;
	let string_ids:Vec<&str> = ids.split(',').collect();
	let mut ids:Vec<i64> = Vec::new();

	let vecter_iterator = string_ids.iter();
	for id in vecter_iterator {
		ids.push(id.parse::<i64>().unwrap());
	}

	let _result = service_clone_all_roles(ids).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn clone_role(Form(role_request):Form<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let _result = service_clone_role(id).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn delete_all_roles(Form(ids_request):Form<IdsRequest>) ->String {
	let ids = ids_request.ids;
	let string_ids:Vec<&str> = ids.split(',').collect();
	let mut ids:Vec<i64> = Vec::new();

	let vecter_iterator = string_ids.iter();
	for id in vecter_iterator {
		ids.push(id.parse::<i64>().unwrap());
	}

	let _result = service_delete_all_roles(ids).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn delete_role(Form(role_request):Form<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let _result = service_delete_role(id).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn export_roles() ->Response<Body> {
	let list = service_list_all_roles().await.unwrap();
	let mut contents : Vec<Vec<String>> = Vec::new();
	let sheet_name = "角色信息表".to_string();
	let headers = vec!["序号".to_string(),"名字".to_string(),"活跃".to_string()];
	let is_images = vec![false,false,false];
	for role in list {

		let row = vec![role.id.to_string(),role.role_name,role.active.to_string()];
		contents.push(row);
	}

	let full_file_path = "./template/temp/roles.xlsx";
	export_excel_workbook_with_image(full_file_path.to_string(),sheet_name, headers, contents, is_images);
	
	
	let data = fs::read(full_file_path).unwrap();
	let _ = fs::remove_file(full_file_path);

	Response::builder()
	.header("Content-Type", "application/octet-stream")
	.header("Content-Disposition", "attachment; filename=roles.xlsx")
	.header("Content-Transfer-Encoding", "binary")
	.body(Body::from(data))
	.unwrap()
}

pub async fn export_roles_pdf() ->Response<Body> {
	let list = service_list_all_roles().await.unwrap();
	let mut contents : Vec<Vec<String>> = Vec::new();
	let sheet_name = "角色信息表".to_string();
	let headers = vec!["序号".to_string(),"名字".to_string(),"活跃".to_string()];
	let is_images = vec![false,false,false];
	for role in list {

		let row = vec![role.id.to_string(),role.role_name,role.active.to_string()];
		contents.push(row);
	}

	let data = export_pdf_with_images(sheet_name, headers, contents, is_images);
	
	Response::builder()
	.header("Content-Type", "application/octet-stream")
	.header("Content-Disposition", "attachment; filename=roles.pdf")
	.header("Content-Transfer-Encoding", "binary")
	.body(Body::from(data))
	.unwrap()
}

pub async fn filter_roles_excel(Query(role_query_request):Query<RoleQueryRequest>) ->Response<Body> {
	let list = service_search_roles_by_fields(role_query_request).await.unwrap();
	let mut contents : Vec<Vec<String>> = Vec::new();
	let sheet_name = "角色信息表".to_string();
	let headers = vec!["序号".to_string(),"名字".to_string(),"活跃".to_string()];
	let is_images = vec![false,false,false];
	for role in list {

		let row = vec![role.id.to_string(),role.role_name,role.active.to_string()];
		contents.push(row);
	}

	let full_file_path = "./template/temp/roles.xlsx";
	export_excel_workbook_with_image(full_file_path.to_string(),sheet_name, headers, contents, is_images);
	
	
	let data = fs::read(full_file_path).unwrap();
	let _ = fs::remove_file(full_file_path);

	Response::builder()
	.header("Content-Type", "application/octet-stream")
	.header("Content-Disposition", "attachment; filename=roles.xlsx")
	.header("Content-Transfer-Encoding", "binary")
	.body(Body::from(data))
	.unwrap()
}

pub async fn filter_roles_pdf(Query(role_query_request):Query<RoleQueryRequest>) ->Response<Body> {
	let list = service_search_roles_by_fields(role_query_request).await.unwrap();
	let mut contents : Vec<Vec<String>> = Vec::new();
	let sheet_name = "角色信息表".to_string();
	let headers = vec!["序号".to_string(),"名字".to_string(),"活跃".to_string()];
	let is_images = vec![false,false,false];
	for role in list {

		let row = vec![role.id.to_string(),role.role_name,role.active.to_string()];
		contents.push(row);
	}

	let data = export_pdf_with_images(sheet_name, headers, contents, is_images);

	Response::builder()
	.header("Content-Type", "application/octet-stream")
	.header("Content-Disposition", "attachment; filename=roles.pdf")
	.header("Content-Transfer-Encoding", "binary")
	.body(Body::from(data))
	.unwrap()
}

pub async fn find_role_by_id(Form(role_request):Form<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let role = service_find_role_by_id(id).await;
	match role {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(role) => {
			let json = serde_json::to_string_pretty(&role).unwrap();

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);
		
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn find_role_by_role_name(Form(role_request):Form<RoleRequest>) ->String {
	let role_name = role_request.role_name.unwrap_or_default();
	let role = service_find_role_by_role_name(role_name).await;
	match role {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(role) => {
			let json = serde_json::to_string_pretty(&role).unwrap();

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);
		
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn list_active_role_permissions_using_role_id(Form(role_permission_mtm_request):Form<RolePermissionMtmRequest>) ->String {
	let role_id = role_permission_mtm_request.role_id.unwrap_or_default();

	let permissions = service_list_active_role_permissions_using_role_id(role_id).await;
	match permissions {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(permissions) => {
			let json = serde_json::to_string_pretty(&permissions).unwrap();

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);
		
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn list_active_roles() ->String {
	let roles = service_list_active_roles().await;
	match roles {
		Err(_) => {
			println!("Error!");
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(roles) => {
			let json = serde_json::to_string_pretty(&roles).unwrap();
			//println!("{}", json);

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);
		
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			//println!("{}", resultjson);
			return resultjson;
		}
	}
}

pub async fn list_all_roles() ->String {
	let roles = service_list_all_roles().await;
	match roles {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(roles) => {
			let json = serde_json::to_string_pretty(&roles).unwrap();

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);
		
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn list_available_active_role_permissions_using_role_id(Form(role_permission_mtm_request):Form<RolePermissionMtmRequest>) ->String {
	let id = role_permission_mtm_request.role_id.unwrap_or_default();

	let permissions = service_list_available_active_role_permissions_using_role_id(id).await;
	match permissions {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(permissions) => {
			let json = serde_json::to_string_pretty(&permissions).unwrap();

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);
		
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn revoke_permissions_from_role(Form(role_permission_mtm_request):Form<RolePermissionMtmRequest>) ->String {
	let role_id = role_permission_mtm_request.role_id.unwrap_or_default();
	let permission_ids_str = role_permission_mtm_request.permission_ids.unwrap_or_default();
	let string_ids:Vec<&str> = permission_ids_str.split(',').collect();
	let mut permission_ids:Vec<i64> = Vec::new();

	let vecter_iterator = string_ids.iter();
	for permission_id in vecter_iterator {
		permission_ids.push(permission_id.parse::<i64>().unwrap());
	}

	let _result = service_revoke_permissions_from_role(role_id,permission_ids).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn search_roles_by_fields_by_page(Form(role_query_request):Form<RoleQueryRequest>) ->String {
	let roles = service_search_roles_by_fields_by_page(role_query_request.clone()).await;
	let total = service_count_search_roles_by_fields_records(role_query_request.clone()).await.unwrap().count_num;
	match roles {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(roles) => {
			let json = serde_json::to_string_pretty(&roles).unwrap();

			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert("total".to_string(), Value::from(total));
			map.insert(
				"rows".to_string(),
				serde_json::from_str(&json).unwrap(),
			);
		
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn soft_delete_all_roles(Form(ids_request):Form<IdsRequest>) ->String {
	let ids = ids_request.ids;
	let string_ids:Vec<&str> = ids.split(',').collect();
	let mut ids:Vec<i64> = Vec::new();

	let vecter_iterator = string_ids.iter();
	for id in vecter_iterator {
		ids.push(id.parse::<i64>().unwrap());
	}

	let _result = service_soft_delete_all_roles(ids).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn soft_delete_role(Form(role_request):Form<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let _result = service_soft_delete_role(id).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn toggle_one_role(Form(role_request):Form<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let _result = service_toggle_one_role(id).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn toggle_role(Form(role_request):Form<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let _result = service_toggle_role(id).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

pub async fn update_role(Json(role_request):Json<RoleRequest>) ->String {
	let id = role_request.id.unwrap_or_default();
	let role_name = role_request.role_name.unwrap_or_default();
	let active = role_request.active.unwrap_or_default();
	let _current_role = service_find_role_by_id(id).await.unwrap();

	let role = RoleBean{
	id : id,
	role_name : role_name,
	active : active,
	};
	
	let _result = service_update_role(role).await;
	match _result {
		Err(_) => {
			r#"{  "rows": null,  "success": true}"#.to_string()
		},
		Ok(_result) => {
			let mut map = Map::new();
			map.insert("success".to_string(), Value::from(true));
			map.insert(
				"rows".to_string(),
				Value::from(""),
			);
			
			let resultjson = serde_json::to_string_pretty(&map).unwrap();
			return resultjson;
		}
	}
}

